﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Cms.Domain;

namespace Cms.Tests.Unit.Domain
{

    [TestClass]
    public class PageTests
    {

        [TestMethod]
        public void GetPublishedContentHtmlAndTitle_AreaAndContentExists_Success()
        {
            Page p = new Page();
            Content c = new Content();
            Locale locale = new Locale { ID = 1 };
            Administrator admin = new Administrator() { ID = 1 };
            PageContentLink pageLink = new PageContentLink { Content = c, Page = p, AreaID = "pcMain" };
            p.Content.Add(pageLink);
            ContentTranslationVersion ctv = c.AddVersion(locale, DateTime.Now.Ticks, "some html", "title", admin);
            ctv.Translation.PublishedVersion = ctv;
            Assert.AreEqual("some html", p.GetPublishedContentHtml("pcMain", 1));
            Assert.AreEqual("title", p.GetPublishedContentTitle("pcMain", 1));
        }


        [TestMethod]
        public void GetContentHtmlAndTitle_AreaAndContentExists_Success()
        {
            Page p = new Page();
            Content c = new Content();
            Locale locale = new Locale { ID = 1 };
            Administrator admin = new Administrator() { ID = 1 };
            PageContentLink pageLink = new PageContentLink { Content = c, Page = p, AreaID = "pcMain" };
            p.Content.Add(pageLink);
            c.AddVersion(locale, 1001, "html 1", "title 1", admin);
            c.AddVersion(locale, 1002, "html 2", "title 2", admin);
            c.AddVersion(locale, 1003, "html 3", "title 3", admin);
            Assert.AreEqual("html 2", p.GetContentHtml("pcMain", 1, "1002"));
            Assert.AreEqual("title 2", p.GetContentTitle("pcMain", 1, "1002"));
        }


        [TestMethod]
        public void GetContent_AreaAndContentExists_Success()
        {
            Page p = new Page();
            Content c = new Content { ID = 1 };
            PageContentLink pageLink = new PageContentLink { Content = c, Page = p, AreaID = "pcMain" };
            p.Content.Add(pageLink);
            Assert.AreEqual(1, p.GetContent("pcMain").ID);
        }


        [TestMethod]
        public void GetVirtualPath_Success()
        {
            Folder folderA = new Folder { Name = "folderA" };
            Folder folderB = new Folder { Name = "folderB", Parent = folderA };
            Page p = new Page {Filename = "page.aspx", Folder = folderB};
            folderA.SubFolders.Add(folderB);
            folderB.Pages.Add(p);
            Assert.AreEqual("folderA/folderB/page.aspx", p.GetVirtualPath());            
        }


        [TestMethod]
        public void AddContentLink_NoPreviousContentInArea_Success()
        {
            Page p = new Page();
            Content c = new Content { ID = 1 };
            p.AddContentLink("pcMain", c);
            Assert.AreSame(c, p.GetContent("pcMain"));
        }


        [TestMethod]
        public void AddContentLink_ExistingContentHasVersions_ExistingVersionsAreDeletedFromContentSet()
        {
            // Setup a page with a few content versions
            Page p = new Page();
            Locale locale = new Locale {ID = 1};
            Administrator admin = new Administrator();
            Content c = new Content { ID = 1 };
            long timestamp = DateTime.Now.Ticks;
            p.AddContentLink("pcMain", c);
            ContentTranslationVersion ctv = c.AddVersion(locale, timestamp, "1", "1", admin);
            p.GetContentSet(locale).TranslationVersions.Add(ctv);
            ctv = c.AddVersion(locale, timestamp + 600000000, "1", "1", admin); // + 1 minute
            p.GetContentSet(locale).TranslationVersions.Add(ctv);
            ctv = c.AddVersion(locale, timestamp + 1200000000, "1", "1", admin); // + 2 minutes
            p.GetContentSet(locale).TranslationVersions.Add(ctv);
            Assert.AreEqual(3, p.GetContentSet(locale).TranslationVersions.Count);
            // Now select another content
            Content c2 = new Content();
            p.AddContentLink("pcMain", c2);
            Assert.AreEqual(0, p.GetContentSet(locale).TranslationVersions.Count);
        }


        [TestMethod]
        public void IsInCategory_ParentFolderIsAssociated_Success()
        {
            Folder a = new Folder {Name = "a"};
            Page p = new Page {Folder = a};
            Category category = new Category() { ID = 1, Name = "Services" };
            a.Categories.Add(category);
            category.Folders.Add(a);
            Assert.IsTrue(p.IsInCategory("Services"));
        }


        [TestMethod]
        public void GetAllCategories_BothPageAndFolderHasCategories_AllCategoriesAreReturned()
        {
            Folder f1 = new Folder() { ID = 1 };
            Folder f2 = new Folder() { ID = 2 };
            Page p = new Page {Folder = f2};
            f2.Pages.Add(p);
            f1.SubFolders.Add(f2);
            f2.Parent = f1;
            Category pcVehicles = new Category() { ID = 1, Name = "Vehicles" };
            Category pcCars = new Category() { ID = 2, Name = "Cars" };
            Category pcVolvo = new Category() { ID = 3, Name = "Volvo" };
            p.Categories.Add(pcVolvo);
            f1.Categories.Add(pcVehicles);
            f2.Categories.Add(pcCars);
            // Check that the correct number of categories is returned
            Assert.AreEqual(3, p.GetAllCategories().Count);
            // Check that they are returned in the correct order, starting with the page and then upwards in the folder hierarchy
            Assert.AreSame(pcVolvo, p.GetAllCategories()[0]);
            Assert.AreSame(pcCars, p.GetAllCategories()[1]);
            Assert.AreSame(pcVehicles, p.GetAllCategories()[2]);
        }


        [TestMethod]
        public void GetCategoryNames_BothPageAndFolderHasCategories_StringWithVolvoCarsVehicles()
        {
            Folder f1 = new Folder() { ID = 1 };
            Folder f2 = new Folder() { ID = 2 };
            Page p = new Page { Folder = f2 };
            f2.Pages.Add(p);
            f1.SubFolders.Add(f2);
            f2.Parent = f1;
            Category pcVehicles = new Category() { ID = 1, Name = "Vehicles" };
            Category pcCars = new Category() { ID = 2, Name = "Cars" };
            Category pcVolvo = new Category() { ID = 3, Name = "Volvo" };
            p.Categories.Add(pcVolvo);
            f1.Categories.Add(pcVehicles);
            f2.Categories.Add(pcCars);
            Assert.AreEqual("Volvo, Cars, Vehicles", string.Join(", ", p.GetCategoryNames()));
        }

        [TestMethod]
        public void GetPublishedTimestamp_LocaleDoesntExist_Null()
        {
            Page p = new Page();
            Assert.IsNull(p.GetPublishedTimestamp(1));
        }

        [TestMethod]
        public void GetPublishedTimestamp_NoPublishedContent_Null()
        {
            Page p = new Page();
            Content c = new Content { ID = 1 };
            PageContentLink pageLink = new PageContentLink { Content = c, Page = p, AreaID = "pcMain" };
            p.Content.Add(pageLink);
            Assert.AreEqual(1, p.GetContent("pcMain").ID);
        }

        [TestMethod]
        public void AllowsAdministrator_PermissionGrantedByDefaultAccessAllow_ReturnTrue()
        {
            Page page = new Page();
            AdministratorGroup group = new AdministratorGroup();
            group.DefaultPageAccess = DefaultAccess.Allow;
            Administrator admin = new Administrator();
            admin.Group = group;
            Assert.IsTrue(page.AllowsAdministrator(admin));
        }
    }
}
